<template>
  <div class="min-h-screen bg-gradient-to-br from-gray-50 to-gray-100 py-8">
    <div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
      <div class="text-center mb-8">
        <h1 class="text-3xl font-bold text-gray-900 mb-2">条形码生成器</h1>
        <p class="text-gray-600">支持多种条码类型，实时预览并可下载为图片</p>
      </div>

      <div class="bg-white rounded-xl shadow-lg p-6">
        <div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
          <!-- Left: controls -->
          <div>
            <div class="mb-4">
              <label class="block text-sm font-medium text-gray-700 mb-2">内容</label>
              <input v-model="inputText" @input="generateBarcode" type="text" placeholder="请输入要编码的内容"
                class="input-field w-full" />
              <div class="mt-2 text-sm text-gray-500">长度: {{ inputText.length }}</div>
            </div>

            <div class="mb-4">
              <label class="block text-sm font-medium text-gray-700 mb-2">条码类型</label>
              <select v-model="barcodeType" @change="generateBarcode" class="input-field w-full">
                <option value="CODE128">CODE128（常用）</option>
                <option value="CODE39">CODE39</option>
                <option value="EAN13">EAN13（商品条码）</option>
                <option value="UPC">UPC</option>
                <option value="ITF">ITF</option>
                <option value="EAN8">EAN8</option>
              </select>
            </div>

            <div class="mb-4 grid grid-cols-2 gap-4">
              <div>
                <label class="block text-sm font-medium text-gray-700 mb-2">宽度 (单条线宽度 px)</label>
                <input type="range" min="1" max="4" v-model.number="lineWidth" @input="generateBarcode" class="w-full">
                <div class="text-sm text-gray-500">当前: {{ lineWidth }} px</div>
              </div>
              <div>
                <label class="block text-sm font-medium text-gray-700 mb-2">高度 (px)</label>
                <input type="range" min="40" max="300" step="10" v-model.number="height" @input="generateBarcode" class="w-full">
                <div class="text-sm text-gray-500">当前: {{ height }} px</div>
              </div>
            </div>

            <div class="mb-4 grid grid-cols-2 gap-4">
              <div>
                <label class="block text-sm font-medium text-gray-700 mb-2">前景色</label>
                <input type="color" v-model="lineColor" @input="generateBarcode" class="w-12 h-12 p-0">
              </div>
              <div>
                <label class="block text-sm font-medium text-gray-700 mb-2">背景色</label>
                <input type="color" v-model="backgroundColor" @input="generateBarcode" class="w-12 h-12 p-0">
              </div>
            </div>

            <div class="mb-4">
              <label class="inline-flex items-center">
                <input type="checkbox" v-model="displayValue" @change="generateBarcode" class="form-checkbox">
                <span class="ml-2 text-sm text-gray-700">显示文本</span>
              </label>
            </div>

            <div class="flex flex-wrap gap-3">
              <button @click="generateBarcode" class="primary-button" :disabled="!inputText">生成条形码</button>
              <button @click="downloadBarcode" class="secondary-button" :disabled="!hasBarcode">下载图片</button>
              <button @click="clearAll" class="secondary-button">清空</button>
              <button @click="loadSample" class="secondary-button">加载示例</button>
            </div>
          </div>

          <!-- Right: preview -->
          <div class="flex flex-col items-center">
            <h3 class="text-lg font-semibold text-gray-900 mb-3">预览</h3>

            <div class="bg-white border-2 border-gray-200 rounded-lg p-4 flex items-center justify-center"
              :style="{ width: previewWidth + 'px', height: previewHeight + 'px' }">
              <div class="text-center">
                <svg ref="svgRef" v-show="hasBarcode" :width="svgWidth" :height="height" xmlns="http://www.w3.org/2000/svg"></svg>
                <div v-if="!hasBarcode" class="text-center text-gray-500">
                  <svg class="w-16 h-16 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                      d="M12 4v1m6 11h2m-6 0h-2v4m0-11v3m0 0h.01M12 12h4.01M16 20h4M4 12h4m12 0h.01M5 8h2a1 1 0 001-1V5a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1zm12 0h2a1 1 0 001-1V5a1 1 0 00-1-1h-2a1 1 0 00-1 1v2a1 1 0 001 1zM5 20h2a1 1 0 001-1v-2a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1z"></path>
                  </svg>
                  <p>请输入内容并点击生成</p>
                </div>
              </div>
            </div>

            <div v-if="hasBarcode" class="mt-4 text-sm text-gray-600">
              <div>类型: {{ barcodeType }}</div>
              <div>尺寸: 宽度自适应 × {{ height }} px</div>
            </div>
          </div>
        </div>
      </div>

      <div class="mt-6 bg-white rounded-xl shadow-lg p-6 text-sm text-gray-600">
        <h3 class="font-semibold mb-2">使用说明</h3>
        <ul class="list-disc pl-5 space-y-1">
          <li>选择条码类型并输入要编码的内容</li>
          <li>点击“生成条形码”或更改设置后将自动预览</li>
          <li>点击“下载图片”将条码保存为 PNG</li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, watch, onMounted } from 'vue'



const inputText = ref('')
const barcodeType = ref('CODE128')
const lineWidth = ref(2)
const height = ref(100)
const lineColor = ref('#000000')
const backgroundColor = ref('#ffffff')
const displayValue = ref(true)

const svgRef = ref(null)
const hasBarcode = ref(false)

const svgWidth = ref(300)
const previewWidth = ref(360)
const previewHeight = ref(200)

// 动态计算预览容器宽度
watch([inputText, lineWidth], () => {
  // 简单估算：根据字符数和线宽调整 svg 宽度
  const base = Math.max(120, inputText.value.length * 8 * (lineWidth.value / 2))
  svgWidth.value = Math.min(1200, Math.max(base, 120))
  previewWidth.value = svgWidth.value + 32
  previewHeight.value = height.value + 32
})

// 生成条形码（仅在浏览器端执行）
const generateBarcode = async () => {
  // 在 SSR 环境或无 window 时跳过
  if (typeof window === 'undefined') return

  if (!inputText.value.trim()) {
    hasBarcode.value = false
    return
  }

  try {
    // 动态导入 jsbarcode（只导入一次）
    const mod = await import('jsbarcode')
    const JsBarcode = mod.default ?? mod

    // 清空 svg
    const svgEl = svgRef.value
    if (!svgEl) return
    while (svgEl.firstChild) svgEl.removeChild(svgEl.firstChild)

    // 使用 JsBarcode 在 svg 上渲染
    JsBarcode(svgEl, inputText.value, {
      format: barcodeType.value,
      lineColor: lineColor.value,
      width: lineWidth.value,
      height: height.value,
      displayValue: displayValue.value,
      background: backgroundColor.value,
      margin: 10,
      fontSize: 14
    })

    hasBarcode.value = true
  } catch (error) {
    console.error('生成条形码失败', error)
    hasBarcode.value = false
  }
}

// 将 SVG 转为 PNG 并下载
const downloadBarcode = async () => {
  if (!hasBarcode.value) return

  try {
    const svgEl = svgRef.value
    const serializer = new XMLSerializer()
    const svgString = serializer.serializeToString(svgEl)
    const svgBlob = new Blob([svgString], { type: 'image/svg+xml;charset=utf-8' })
    const url = URL.createObjectURL(svgBlob)

    // 将 SVG 绘制到 canvas
    const img = new Image()
    img.onload = () => {
      const canvas = document.createElement('canvas')
      canvas.width = img.width
      canvas.height = img.height
      const ctx = canvas.getContext('2d')
      // 填充背景
      ctx.fillStyle = backgroundColor.value || '#ffffff'
      ctx.fillRect(0, 0, canvas.width, canvas.height)
      ctx.drawImage(img, 0, 0)
      const dataUrl = canvas.toDataURL('image/png')

      const link = document.createElement('a')
      link.download = `barcode-${Date.now()}.png`
      link.href = dataUrl
      link.click()
      URL.revokeObjectURL(url)
    }
    img.onerror = (e) => {
      URL.revokeObjectURL(url)
      console.error('SVG -> Image 转换失败', e)
    }
    img.src = url
  } catch (error) {
    console.error('下载失败', error)
  }
}

const clearAll = () => {
  inputText.value = ''
  hasBarcode.value = false
}

const loadSample = () => {
  switch (barcodeType.value) {
    case 'EAN13':
      inputText.value = '6901234567890'
      break
    case 'UPC':
      inputText.value = '012345678905'
      break
    case 'EAN8':
      inputText.value = '1234567'
      break
    default:
      inputText.value = 'HELLO-123456'
      break
  }
  generateBarcode()
}

// 立即生成（如果有内容），仅在客户端执行
onMounted(() => {
  watch([inputText, barcodeType, lineWidth, height, lineColor, backgroundColor, displayValue], () => {
    generateBarcode()
  }, { immediate: true })
})

useHead({
  title: '条形码生成器 - 八八在线工具',
  meta: [{ name: 'description', content: '在线条形码生成器，支持 CODE128、EAN13 等多种格式，支持下载图片' }]
})
</script>

<style scoped>
/* 保持与项目风格一致的输入与按钮类（项目已有全局类，这里不重复） */
</style>
